﻿using System;
using System.ServiceModel.Channels;
using System.Threading;

namespace Microsoft.Biztalk.Adapters.Wcf.NullBinding
{
    class NullChannelListener<TChannel> : ChannelListenerBase<TChannel> where TChannel : class, IChannel
    {
        int channelAcceptedCount;
        NullBindingProperties properties;

        public NullChannelListener(NullBindingProperties properties)
        {
            this.channelAcceptedCount = 0;
            this.properties = properties;
        }

        protected override TChannel OnAcceptChannel(TimeSpan timeout)
        {
            if (this.channelAcceptedCount < this.properties.NumberOfThreads)
            {
                this.channelAcceptedCount++;
                if (typeof(TChannel) == typeof(IInputChannel))
                {
                    return (TChannel)(object)(new NullInputChannel(this, this.properties));
                }
                else
                {
                    return (TChannel)(object)(new NullReplyChannel(this, this.properties));
                }
            }
            return null;
        }

        protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override TChannel OnEndAcceptChannel(IAsyncResult result)
        {
            return OnAcceptChannel(this.DefaultReceiveTimeout);
        }

        protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override bool OnEndWaitForChannel(IAsyncResult result)
        {
            return true;
        }

        protected override bool OnWaitForChannel(TimeSpan timeout)
        {
            return true;
        }

        public override Uri Uri
        {
            get { return new Uri(Helpers.Address); }
        }

        protected override void OnAbort()
        {
        }

        protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
        {
            return new NullAsyncResult(callback, state);
        }

        protected override void OnClose(TimeSpan timeout)
        {
        }

        protected override void OnEndClose(IAsyncResult result)
        {
        }

        protected override void OnEndOpen(IAsyncResult result)
        {
        }

        protected override void OnOpen(TimeSpan timeout)
        {
        }
    }
}
